package com.lixixi.tingshu.common.aspect;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.lixixi.tingshu.common.anno.NeedLogin;
import com.lixixi.tingshu.common.constant.RedisConstant;
import com.lixixi.tingshu.common.result.ResultCodeEnum;
import com.lixixi.tingshu.common.util.AuthContextHolder;
import com.lixixi.tingshu.exception.BaseException;
import com.lixixi.tingshu.model.user.UserInfo;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.concurrent.TimeUnit;

@Aspect
@Component
public class LoginAspect {

	@Autowired
	RedisTemplate<String, String> redisTemplate;

	@Around("execution(* com.lixixi.tingshu.*.api.*.*(..)) && @annotation(needLogin)")
	public Object around(ProceedingJoinPoint point, NeedLogin needLogin) throws Throwable {
		//根据Servlet上下文获取当前请求对象
		ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = requestAttributes.getRequest();
		//获取token值
		String token = request.getHeader("token");
		//判断是否需要登录
		if (needLogin.isLogin())
		{
			//查询请求头是否带有登录token值
			if (StringUtils.isEmpty(token))
				throw new BaseException(ResultCodeEnum.LOGIN_AUTH);
			//判断token值在缓存中是否有效
			//有,更新缓存过期时间
			String userInfoJson = redisTemplate.opsForValue().getAndExpire(RedisConstant.USER_LOGIN_KEY_PREFIX + token
					, RedisConstant.USER_LOGIN_KEY_TIMEOUT, TimeUnit.SECONDS);
			//无则抛出异常重新登录
			if (StringUtils.isEmpty(userInfoJson))
				throw new BaseException(ResultCodeEnum.LOGIN_AUTH);
			//缓存有效存入本地线程变量
			UserInfo userInfo = JSONObject.parseObject(userInfoJson, UserInfo.class);
			AuthContextHolder.setUserId(userInfo.getId());
			AuthContextHolder.setUsername(userInfo.getNickname());
		} else
		{
			//根据token获取缓存值
			//有,更新缓存过期时间
			String userInfoJson = redisTemplate.opsForValue().getAndExpire(RedisConstant.USER_LOGIN_KEY_PREFIX + token
					, RedisConstant.USER_LOGIN_KEY_TIMEOUT, TimeUnit.SECONDS);
			if (!StringUtils.isEmpty(userInfoJson))
			{
				//缓存有效存入本地线程变量
				UserInfo userInfo = JSONObject.parseObject(userInfoJson, UserInfo.class);
				AuthContextHolder.setUserId(userInfo.getId());
				AuthContextHolder.setUsername(userInfo.getNickname());
			}
		}
		return point.proceed();
	}
}
